const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const cors = require('cors');
const path = require('path');
const SimpleDatabase = require('./database');

const app = express();
const PORT = process.env.PORT || 3003;
const HOST = process.env.HOST || '0.0.0.0'; // 监听所有网络接口
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production';

// 配置允许的域名
const allowedOrigins = process.env.ALLOWED_ORIGINS 
    ? process.env.ALLOWED_ORIGINS.split(',')
    : ['http://localhost:3003', 'http://101.35.132.66:3003'];

// 中间件
app.use(express.json());
app.use(cookieParser());
// 配置CORS允许外网访问
app.use(cors({
    origin: allowedOrigins,
    credentials: true
}));
app.use(express.static('public'));

// 数据库实例
const db = new SimpleDatabase();

// 创建默认管理员账户
const createAdminUser = async () => {
    if (!db.getUser('admin')) {
        const adminPassword = await bcrypt.hash('admin123', 10);
        db.addUser('admin', {
            username: 'admin',
            password: adminPassword,
            role: 'admin',
            createdAt: new Date(),
            isActive: true
        });
        console.log('管理员账户已创建: admin / admin123');
    } else {
        console.log('管理员账户已存在');
    }
};

createAdminUser();

// JWT验证中间件
const authenticateToken = (req, res, next) => {
    const token = req.cookies.token;
    
    if (!token) {
        return res.status(401).json({ error: '未授权访问' });
    }

    jwt.verify(token, JWT_SECRET, (err, user) => {
        if (err) {
            return res.status(403).json({ error: '令牌无效' });
        }
        req.user = user;
        next();
    });
};

// 管理员权限中间件
const requireAdmin = (req, res, next) => {
    if (req.user.role !== 'admin') {
        return res.status(403).json({ error: '需要管理员权限' });
    }
    next();
};

// 路由

// 注册
app.post('/api/register', async (req, res) => {
    try {
        const { username, password, confirmPassword } = req.body;

        // 验证输入
        if (!username || !password || !confirmPassword) {
            return res.status(400).json({ error: '请填写所有字段' });
        }

        if (password !== confirmPassword) {
            return res.status(400).json({ error: '密码确认不匹配' });
        }

        if (password.length < 6) {
            return res.status(400).json({ error: '密码至少需要6个字符' });
        }

        // 检查用户是否已存在
        if (db.getUser(username)) {
            return res.status(400).json({ error: '用户名已存在' });
        }

        // 创建新用户
        const hashedPassword = await bcrypt.hash(password, 10);
        db.addUser(username, {
            username,
            password: hashedPassword,
            role: 'user',
            createdAt: new Date(),
            isActive: true
        });

        res.json({ message: '注册成功' });
    } catch (error) {
        res.status(500).json({ error: '服务器错误' });
    }
});

// 登录
app.post('/api/login', async (req, res) => {
    try {
        const { username, password } = req.body;

        // 验证输入
        if (!username || !password) {
            return res.status(400).json({ error: '请输入用户名和密码' });
        }

        // 检查用户是否存在
        const user = db.getUser(username);
        if (!user) {
            return res.status(400).json({ error: '用户名或密码错误' });
        }

        // 检查用户是否被禁用
        if (!user.isActive) {
            return res.status(400).json({ error: '账户已被禁用' });
        }

        // 验证密码
        const isValidPassword = await bcrypt.compare(password, user.password);
        if (!isValidPassword) {
            return res.status(400).json({ error: '用户名或密码错误' });
        }

        // 生成JWT令牌
        const token = jwt.sign(
            { username: user.username, role: user.role },
            JWT_SECRET,
            { expiresIn: '24h' }
        );

        // 更新最后登录时间
        db.updateUserLogin(username);

        // 设置cookie
        res.cookie('token', token, {
            httpOnly: true,
            maxAge: 24 * 60 * 60 * 1000 // 24小时
        });

        res.json({
            message: '登录成功',
            user: {
                username: user.username,
                role: user.role
            }
        });
    } catch (error) {
        res.status(500).json({ error: '服务器错误' });
    }
});

// 退出登录
app.post('/api/logout', (req, res) => {
    res.clearCookie('token');
    res.json({ message: '退出成功' });
});

// 获取当前用户信息
app.get('/api/user', authenticateToken, (req, res) => {
    const user = db.getUser(req.user.username);
    if (!user) {
        return res.status(404).json({ error: '用户不存在' });
    }
    res.json({
        username: user.username,
        role: user.role,
        createdAt: user.createdAt,
        lastLogin: user.lastLogin
    });
});

// 保存游戏数据
app.post('/api/game-data/:gameName', authenticateToken, (req, res) => {
    const { gameName } = req.params;
    const { data } = req.body;
    const key = `${req.user.username}_${gameName}`;
    
    const gameDataToSave = {
        ...data,
        updatedAt: new Date()
    };
    
    db.setGameData(key, gameDataToSave);
    
    // 如果是新的游戏记录，添加到游戏记录中
    if (data.lastScore !== undefined) {
        db.addGameRecord(req.user.username, gameName, {
            score: data.lastScore,
            level: data.level,
            lines: data.lines,
            time: data.time,
            moves: data.moves
        });
    }
    
    res.json({ message: '游戏数据已保存' });
});

// 获取游戏数据
app.get('/api/game-data/:gameName', authenticateToken, (req, res) => {
    const { gameName } = req.params;
    const key = `${req.user.username}_${gameName}`;
    const data = db.getGameData(key) || {};
    
    res.json(data);
});

// 管理员路由

// 获取所有用户
app.get('/api/admin/users', authenticateToken, requireAdmin, (req, res) => {
    const userList = db.getAllUsers().map(user => {
        const userStats = db.getUserStats(user.username);
        const totalGames = Object.values(userStats).reduce((sum, stats) => sum + stats.totalGames, 0);
        
        return {
            username: user.username,
            role: user.role,
            createdAt: user.createdAt,
            lastLogin: user.lastLogin,
            isActive: user.isActive,
            totalGames: totalGames
        };
    });
    
    res.json(userList);
});

// 禁用/启用用户
app.put('/api/admin/users/:username/toggle', authenticateToken, requireAdmin, (req, res) => {
    const { username } = req.params;
    const user = db.getUser(username);
    
    if (!user) {
        return res.status(404).json({ error: '用户不存在' });
    }
    
    if (username === 'admin') {
        return res.status(400).json({ error: '不能禁用管理员账户' });
    }
    
    const updatedUser = { ...user, isActive: !user.isActive };
    db.updateUser(username, updatedUser);
    
    res.json({ 
        message: `用户已${updatedUser.isActive ? '启用' : '禁用'}`,
        isActive: updatedUser.isActive
    });
});

// 删除用户
app.delete('/api/admin/users/:username', authenticateToken, requireAdmin, (req, res) => {
    const { username } = req.params;
    
    if (username === 'admin') {
        return res.status(400).json({ error: '不能删除管理员账户' });
    }
    
    if (!db.getUser(username)) {
        return res.status(404).json({ error: '用户不存在' });
    }
    
    db.deleteUser(username);
    
    res.json({ message: '用户已删除' });
});

// 获取总览数据
app.get('/api/admin/overview', authenticateToken, requireAdmin, (req, res) => {
    const allUsers = db.getAllUsers();
    const totalUsers = allUsers.length;
    const activeUsers = allUsers.filter(user => user.isActive).length;
    const allGameData = db.getAllGameData();
    const totalGameSessions = allGameData.size;
    const todayRecords = db.getTodayRecords();
    
    // 计算今日新增用户
    const today = new Date().toDateString();
    const newUsersToday = allUsers.filter(user => 
        new Date(user.createdAt).toDateString() === today
    ).length;
    
    // 计算最受欢迎的游戏
    const gamePopularity = {};
    for (const [key] of allGameData) {
        const gameName = key.split('_')[1];
        gamePopularity[gameName] = (gamePopularity[gameName] || 0) + 1;
    }
    
    const popularGame = Object.keys(gamePopularity).length > 0 ? 
        Object.keys(gamePopularity).reduce((a, b) => 
            gamePopularity[a] > gamePopularity[b] ? a : b
        ) : '俄罗斯方块';
    
    // 今日最佳成绩
    const todayBest = {
        tetris: '暂无记录',
        snake: '暂无记录',
        flappy: '暂无记录'
    };
    
    // 从今日记录中获取最佳成绩
    todayRecords.forEach(record => {
        if (record.gameName === 'tetris' && record.score) {
            const current = todayBest.tetris === '暂无记录' ? 0 : parseInt(todayBest.tetris);
            if (record.score > current) {
                todayBest.tetris = record.score.toString();
            }
        }
        if (record.gameName === 'snake' && record.score) {
            const current = todayBest.snake === '暂无记录' ? 0 : parseInt(todayBest.snake);
            if (record.score > current) {
                todayBest.snake = record.score.toString();
            }
        }
        if (record.gameName === 'flappy' && record.score) {
            const current = todayBest.flappy === '暂无记录' ? 0 : parseInt(todayBest.flappy);
            if (record.score > current) {
                todayBest.flappy = record.score.toString();
            }
        }
    });
    
    res.json({
        totalUsers,
        activeUsers,
        newUsersToday,
        totalGameSessions,
        popularGame,
        todayGames: todayRecords.length,
        avgGameTime: '5分钟',
        onlineUsers: 1,
        todayBest
    });
});

// 获取游戏统计数据
app.get('/api/admin/game-stats', authenticateToken, requireAdmin, (req, res) => {
    const gameStats = {
        tetris: { totalGames: 0, scores: [], activePlayers: new Set() },
        match3: { totalGames: 0, scores: [], completions: 0 },
        minesweeper: { totalGames: 0, wins: 0, times: [] },
        snake: { totalGames: 0, scores: [], lengths: [] },
        flappy: { totalGames: 0, scores: [], passes: 0 },
        memory: { totalGames: 0, completions: 0, times: [], moves: [] }
    };
    
    const allGameData = db.getAllGameData();
    const allRecords = db.getGameRecords();
    
    // 从游戏数据统计
    for (const [key, data] of allGameData) {
        const username = key.split('_')[0];
        const gameName = key.split('_')[1];
        
        if (gameStats[gameName]) {
            const stats = gameStats[gameName];
            
            switch (gameName) {
                case 'tetris':
                    if (data.gamesPlayed) stats.totalGames += data.gamesPlayed;
                    if (data.highScore) {
                        stats.scores.push(data.highScore);
                        stats.activePlayers.add(username);
                    }
                    break;
                    
                case 'match3':
                    if (data.gamesPlayed) stats.totalGames += data.gamesPlayed;
                    if (data.highScore) stats.scores.push(data.highScore);
                    break;
                    
                case 'minesweeper':
                    if (data.gamesPlayed) stats.totalGames += data.gamesPlayed;
                    if (data.gamesWon) stats.wins += data.gamesWon;
                    ['easy', 'medium', 'hard'].forEach(diff => {
                        const time = data[`bestTime_${diff}`];
                        if (time && time !== Infinity) stats.times.push(time);
                    });
                    break;
                    
                case 'snake':
                    if (data.gamesPlayed) stats.totalGames += data.gamesPlayed;
                    if (data.highScore) stats.scores.push(data.highScore);
                    break;
                    
                case 'flappy':
                    if (data.gamesPlayed) stats.totalGames += data.gamesPlayed;
                    if (data.highScore) stats.scores.push(data.highScore);
                    break;
                    
                case 'memory':
                    if (data.gamesPlayed) stats.totalGames += data.gamesPlayed;
                    if (data.gamesCompleted) stats.completions += data.gamesCompleted;
                    break;
            }
        }
    }
    
    // 从游戏记录补充统计
    allRecords.forEach(record => {
        const gameName = record.gameName;
        if (gameStats[gameName] && record.score) {
            // 确保记录中的分数也被统计
            if (!gameStats[gameName].scores.includes(record.score)) {
                gameStats[gameName].scores.push(record.score);
            }
        }
    });
    
    // 计算统计结果
    const result = {};
    
    Object.keys(gameStats).forEach(game => {
        const stats = gameStats[game];
        result[game] = {
            totalGames: stats.totalGames || 0,
            avgScore: (stats.scores && stats.scores.length) ? Math.round(stats.scores.reduce((a, b) => a + b, 0) / stats.scores.length) : 0,
            maxScore: (stats.scores && stats.scores.length) ? Math.max(...stats.scores) : 0,
            activePlayers: stats.activePlayers ? stats.activePlayers.size : 0,
            completionRate: stats.totalGames ? Math.round(((stats.completions || 0) / stats.totalGames) * 100) : 0,
            winRate: stats.totalGames ? Math.round(((stats.wins || 0) / stats.totalGames) * 100) : 0,
            bestTime: (stats.times && stats.times.length) ? Math.min(...stats.times) + 's' : '--',
            avgTime: (stats.times && stats.times.length) ? Math.round(stats.times.reduce((a, b) => a + b, 0) / stats.times.length) + 's' : '--',
            avgLength: (stats.lengths && stats.lengths.length) ? Math.round(stats.lengths.reduce((a, b) => a + b, 0) / stats.lengths.length) : 0,
            passRate: stats.totalGames ? Math.round(((stats.passes || 0) / stats.totalGames) * 100) : 0,
            avgMoves: (stats.moves && stats.moves.length) ? Math.round(stats.moves.reduce((a, b) => a + b, 0) / stats.moves.length) : 0
        };
    });
    
    res.json(result);
});

// 获取特定游戏排行榜
app.get('/api/admin/leaderboard/:gameName', authenticateToken, requireAdmin, (req, res) => {
    const { gameName } = req.params;
    const leaderboard = [];
    const allGameData = db.getAllGameData();
    const gameRecords = db.getGameRecords(gameName);
    
    // 从游戏数据获取最佳成绩
    for (const [key, data] of allGameData) {
        if (key.includes(`_${gameName}`)) {
            const username = key.split('_')[0];
            
            switch (gameName) {
                case 'tetris':
                    if (data.highScore) {
                        leaderboard.push({
                            username,
                            highScore: data.highScore,
                            level: data.level || 1,
                            lines: data.lines || 0,
                            date: data.updatedAt || new Date()
                        });
                    }
                    break;
                    
                case 'match3':
                    if (data.highScore) {
                        leaderboard.push({
                            username,
                            highScore: data.highScore,
                            completionTime: '--',
                            date: data.updatedAt || new Date()
                        });
                    }
                    break;
                    
                case 'snake':
                    if (data.highScore) {
                        leaderboard.push({
                            username,
                            highScore: data.highScore,
                            length: Math.floor(data.highScore / 10) + 1,
                            date: data.updatedAt || new Date()
                        });
                    }
                    break;
                    
                case 'flappy':
                    if (data.highScore) {
                        leaderboard.push({
                            username,
                            highScore: data.highScore,
                            pipes: data.highScore,
                            date: data.updatedAt || new Date()
                        });
                    }
                    break;
                    
                case 'minesweeper':
                    ['easy', 'medium', 'hard'].forEach(diff => {
                        const time = data[`bestTime_${diff}`];
                        if (time && time !== Infinity) {
                            leaderboard.push({
                                username,
                                bestTime: time,
                                difficulty: diff,
                                date: data.updatedAt || new Date()
                            });
                        }
                    });
                    break;
                    
                case 'memory':
                    ['easy', 'medium', 'hard'].forEach(diff => {
                        const time = data[`bestTime_${diff}`];
                        if (time && time !== Infinity) {
                            leaderboard.push({
                                username,
                                bestTime: time,
                                moves: 20, // 可以从记录中获取实际步数
                                date: data.updatedAt || new Date()
                            });
                        }
                    });
                    break;
            }
        }
    }
    
    // 排序
    if (gameName === 'minesweeper' || gameName === 'memory') {
        leaderboard.sort((a, b) => a.bestTime - b.bestTime);
    } else {
        leaderboard.sort((a, b) => b.highScore - a.highScore);
    }
    
    res.json(leaderboard.slice(0, 10));
});

// 获取数据分析
app.get('/api/admin/analytics', authenticateToken, requireAdmin, (req, res) => {
    // 返回分析数据（这里使用模拟数据）
    res.json({
        userActivity: [60, 80, 45, 90, 70, 95, 85],
        gamePopularity: {
            tetris: 85,
            snake: 70,
            match3: 60,
            flappy: 45,
            minesweeper: 40,
            memory: 35
        },
        timeDistribution: [20, 45, 25, 10],
        healthMetrics: {
            retention: 78,
            dailyActive: 92,
            completion: 65,
            stability: 99
        }
    });
});

// 保持原有的stats接口用于兼容
app.get('/api/admin/stats', authenticateToken, requireAdmin, (req, res) => {
    const allUsers = db.getAllUsers();
    const totalUsers = allUsers.length;
    const activeUsers = allUsers.filter(user => user.isActive).length;
    const allGameData = db.getAllGameData();
    const totalGameSessions = allGameData.size;
    
    // 俄罗斯方块排行榜
    const tetrisScores = [];
    let match3HighScore = 0;
    let minesweeperBestTime = null;
    
    for (const [key, data] of allGameData) {
        const username = key.split('_')[0];
        
        if (key.includes('_tetris') && data.highScore) {
            tetrisScores.push({
                username,
                highScore: data.highScore,
                level: data.level || 1,
                lines: data.lines || 0
            });
        }
        
        // 消消乐最高分
        if (key.includes('_match3') && data.highScore) {
            match3HighScore = Math.max(match3HighScore, data.highScore);
        }
        
        // 扫雷最佳时间
        if (key.includes('_minesweeper')) {
            const bestTimes = [
                data.bestTime_easy,
                data.bestTime_medium,
                data.bestTime_hard
            ].filter(time => time && time !== Infinity);
            
            if (bestTimes.length > 0) {
                const userBestTime = Math.min(...bestTimes);
                if (!minesweeperBestTime || userBestTime < minesweeperBestTime) {
                    minesweeperBestTime = userBestTime;
                }
            }
        }
    }
    
    tetrisScores.sort((a, b) => b.highScore - a.highScore);
    
    res.json({
        totalUsers,
        activeUsers,
        totalGameSessions,
        tetrisLeaderboard: tetrisScores.slice(0, 10),
        match3HighScore,
        minesweeperBestTime: minesweeperBestTime ? `${minesweeperBestTime}s` : null
    });
});

// 健康检查端点
app.get('/health', (req, res) => {
    res.json({
        status: 'ok',
        timestamp: new Date().toISOString(),
        uptime: process.uptime(),
        version: require('./package.json').version
    });
});

// 主页路由
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// 启动服务器
app.listen(PORT, HOST, () => {
    console.log(`服务器运行在:`);
    console.log(`  本地访问: http://localhost:${PORT}`);
    console.log(`  网络访问: http://101.35.132.66:${PORT}`);
    console.log('管理员账户: admin / admin123');
});